/*
 * CWikiMarkupParser.cpp
 *
 *  Created on: Sep 6, 2010
 *      Author: data
 */

#include "CWikiMarkupParser.h"
#include "../DictionaryBuilders/AuthorCategoryDict.h"
#include "CWhiteSpaceParser.h"
#include "../Indexer/AuthorIndexer.h"
#include "../Indexer/CategoryIndexer.h"

using namespace std;

/**
 * @brief constructor
 */
CWikiMarkupParser::CWikiMarkupParser() {
	config* configInstance = config::getInstance();
	dirPath = configInstance->getValue("path_to_semwiki_dir");

	CParserState* _parser_state = new CParserState();
	_parser_previous_state = _parser_state;
	_parser_wlb_state = new CWikiLinkBeginState(this);
	_parser_wle_state = new CWikiLinkEndState(this);
	_parser_cc_state = new CWikiCharacterConsumeState(this);
	_parser_pt_state = new CWikiPartialTagState(this);
}

/**
 * @brief destructor
 */
CWikiMarkupParser::~CWikiMarkupParser() {
	delete _parser_cc_state;
	delete _parser_wlb_state;
	delete _parser_wle_state;
	delete _parser_pt_state;
	delete _parser_state;
}

CWikiMarkupParser* CWikiMarkupParser::_wiki_markup_parser = 0;


/*std::string CWikiMarkupParser::CutTextCurlyBraces(){
	ifstream ifs;
	int count = 1;
	string data = "";
	getline(ifs,data);
	cout <<data<<endl;
	return " ";
}*/

/**
 * @brief
 * @param filename
 * @return
 */
bool CWikiMarkupParser::parse_document(CDocument& doc) {
	bool status = false;
	//cout << "Parsing Wiki markup document using a state based tag parser" << endl;
	string file_contents = "";
	string line;
	vector<string> token_vec;
	string delim = "\r\n\t ";

	//cout<<"KING Wiki Parser"<<endl;
	string filename = doc.get_resource_name();
	int i=doc.getDocId();
	std::stringstream docstrm;
	docstrm << i;

	string strDocId="";
	strDocId = docstrm.str();
	//cout<<"DOC ID : "<<i<<endl;
	//cout<<"String DOC Id is : "<<strDocId<<endl;
	//cout<<"FileName is : "<<filename<<endl;
	string sourcename="";

	//cout<<"Sem Wiki File Name Is : "<<semwikifilename<<endl;
	int startPosition = filename.rfind("/");
	int numChar = filename.length()-startPosition-5;
	sourcename = filename.substr(startPosition+1, numChar);
	string semwikifilename=strDocId+"_semwiki_meta_["+sourcename+"].txt";

    string token;
	ifstream ifs (filename.c_str());
	ofstream semWikiStream;
	string semWikiPath=dirPath + "/" + semwikifilename;
	semWikiStream.open(semWikiPath.c_str());
	//cout<<"SemWikiPath is : "<<semWikiPath<<endl;

	// Static Score
	StaticScoreCalc* scoreCalc = StaticScoreCalc::getInstance();


	if ( ifs.is_open() ) {
		int no_of_sections = 0;
		int no_of_references = 0;
		std::string CategoryList;
		string catH = "\n<#CATEGORY>\n";
		int inCategory = 0;
		int headingno = 2;
		std::string AuthorList;
		string autH = "<#AUTHOR>\n";
		std::string Timestamp;
		string timH = "<#TIMESTAMP>\n";
		std::string LinkList;
		string linH = "<#LINKS>\n";
		std::string SectionHeading;
		string secH = "<#SECTIONS>\n";
		std::string infobox;
		string infH = "<#INFOBOX>\n";
		std::string ArticleName = "<#ARTICLE NAME>\n"+sourcename+"\n";
		std::string DOCID = "<#WIKI DOC ID>\n" + strDocId + "\n";
		std::string infoboxfn = "";
		int isHeading=0;
		int isHeading1=0;
		//Gassa commemnt out
		AuthorCategoryDict *AuthCatDict = (AuthorCategoryDict *)AuthorCategoryDict::getInstance();
		CWhiteSpaceParser *WhiteSpaceParser = (CWhiteSpaceParser *)CWhiteSpaceParser::get_instance();
		AuthorIndex* authorIndex = AuthorIndex::getInstance();
		CategoryIndex* categoryIndex = CategoryIndex::getInstance();
		while ( !ifs.eof() ) {
			getline( ifs, line );
            //cout<<line<<endl;
			istringstream iss(line);
			if(line =="" || line == "==" || line == "=")
				continue;
			//Extracting the Infobox Content into the string "infobox" using "extractInfobox" method
			if(line.rfind("{{Infobox")!=string::npos){

				if(line.rfind("<<WikiText>>:")!=string::npos)
					{
						string token="";
						istringstream iss(line);
						getline(iss, token, ' ');
						getline(iss, token, '\n');
						//cout<<"Token after end line is :"<<token<<endl;
						line=token;
					}
				//cout << "Line after WikiText Removal : " << line<<endl;
				extractInfobox(ifs, line, infoboxfn);
				infobox=infobox+infoboxfn;
			}

			//if (infobox != "")continue;

			//cout << "Infobox: " << infobox << "\n";
			//cout<<"Before Author"<<endl;

			if(line[0]=='<'){
            	getline(iss, token, ' ');
            	if (line[1]=='<')
            	{
            		//Extracting the Author Name for both single author and multiple author from the Wiki File and building the Author Dictionary
            	    if(line.rfind("<<Author>>:")!=string::npos){
            	    	//getline(iss, token, '-');
            	    	//cout<<"Initial Line is : "<<token<<endl;

            	    	//If there are multiple authors the line will enter the below if block
            	    	if(line.find(',')!=string::npos)
            	    	{
            	    		std::string::size_type close_pos( 0 );
            	    		close_pos = line.find(',');
							//cout<<"Inside if of Author"<<endl;
							//cout<<"Close Pos is : "<<close_pos<<endl;
            	    		int authorId = -1;
            	    		while(close_pos!=string::npos  )
            	    		{
            	    			getline(iss,token,'-');
            	    			AuthorList = AuthorList.append(token+"$");
            	    			if(token!="")
            	    			{
            	    		    //Gassa comment out
            	    			authorId = AuthCatDict->addAuthor(token);
            	    			authorIndex->addAuthorPostingList(authorId, doc.getDocId(), token);
            	    			AuthCatDict->insertAuthorToFileMap(authorId, doc.getDocId());

            	    			//line=token;
            	    			}
            	    			//if(CUtilities::authors.find(token) == string::npos)
            	    				//CUtilities::authors.append(token+"%");
            	    			//cout<<"After Author Dict Calling"<<endl;
            	    			getline(iss,token,',');
            	    			close_pos+=1;
            	    			//cout<<"Line Length is : "<<line.length();
            	    			//cout<<"Difference is : "<<line.length()-close_pos;
            	    			//cout<<"Close Pos is : "<<close_pos;
            	    			line = line.substr(close_pos,(line.length()-close_pos));
            	    			close_pos = line.find(',');
            	    		}

            	    		getline(iss,token,'-');
            	    		//cout<<token<<endl;

        	    			AuthorList = AuthorList.append(token+"\n");
        	    			cout << "multi author here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << AuthorList << endl;
        	    			//cout<<"Author List is : "<<AuthorList<<endl;

            	    	}
            	    	//If there is a single Author the line will enter the below else block
            	    	else
            	    	{
            	    		//cout<<"In Else "<<endl;
            	    		getline(iss,token,'-');
            	    		if(token!=""){
            	    			line=token;
            	    			AuthorList=AuthorList+token+"\n";
            	    			//Gassa comment out
            	    			int authorId = AuthCatDict->addAuthor(token);
            	    			authorIndex->addAuthorPostingList(authorId, doc.getDocId(), token);
            	    			AuthCatDict->insertAuthorToFileMap(authorId, doc.getDocId());
            	    		}

            	    		//if(CUtilities::authors.find(token) == string::npos)
            	    			//CUtilities::authors.append(token+"%");
            	    	}
            	    	//cout<<"Author List is :"<<AuthorList<<endl;
            	    	//Return the author list
            	    	//check for the author in the author dictionary. If not present create a new author id and append it to the author dictionary
            	    }

            	    //Extracting the Timestamp data for writing in semwiki file
            	    if(line.rfind("<<Timestamp>>:")!=string::npos){
            	    	getline(iss,token,'\n');
            	    	line="";
            	    	Timestamp=Timestamp+token+"\n";
            	    }

            	}else if(line.rfind("<ref>")!=string::npos){
            	    while(line.rfind("</ref>")==string::npos && !(ifs.eof())){
            	    	getline( ifs, line );
            	    }
            	    getline( ifs, line );
            	    //cout<<"REMOVED REF and the next line is"<<line<<endl;
            	}else if(line.rfind("<gallery>")!=string::npos){
            		//cout<<"=======================Inside Gallery Loop================================"<<endl;

            	    while(line.rfind("</gallery>")==string::npos && !(ifs.eof())){
            	    	{
            	    		getline( ifs, line );
            	    	}
            	    }
            	    getline( ifs, line );
            	    //cout<<"REMOVED REF and the next line is"<<line<<endl;
            	}
            	else {
           		}
			}

			//If the line is a heading(i.e., it contains the heading name with the "="'s) the below if block takes the heading name writes it into semwiki file and replace the line with heading name
			if(line[0]=='=')
			{
				//cout<<line<<endl;
				//cout<<"Line in equal to :"<<line<<endl;
				int eqls=0;
				std::string eqlngth="";
				std::string headingname="";
				std::string::size_type start_pos( 0 );
				std::string::size_type end_pos( 0 );
				std::string::size_type last_pos( 0 );
				last_pos=line.find_first_not_of("=");
				eqls=last_pos;
				//cout<<"eqls value is : "<<eqls<<endl;
				//cout<<"End of the Line is : "<<string::npos<<endl;
				//cout<<"=========================Last pos is ========================="<<last_pos<<endl;
				if (last_pos == string::npos)
				{
					//cout<<"============================In Iffffff==============================="<<endl;
					continue;
				}
				else
				{
					no_of_sections++;
					//cout<<"==================In Else================="<<endl;
					for(int i=0;i<headingno;i++){
						eqlngth=eqlngth+"=";
					}

					start_pos=line.find(eqlngth,start_pos);
					start_pos+=eqls;
					end_pos=line.find(eqlngth,start_pos);
					if(start_pos != end_pos-1)
						headingname=line.substr(start_pos,end_pos-start_pos);

					std::remove(headingname.begin(), headingname.end(), ' ');
					line=headingname;

					if(headingname=="References")
					{

						no_of_references = countNoofRef(ifs, line);
					}

					if(isHeading1 == 1)
						SectionHeading=SectionHeading+"\n";
					else
					{
						SectionHeading=SectionHeading+headingname+"$";
						replace(SectionHeading.begin(), SectionHeading.end(), '{', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '!', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '}', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '|', ' ');
						replace(SectionHeading.begin()+1, SectionHeading.end(), '<', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '-', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), ':', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '/', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), ']', ' ');
						replace(SectionHeading.begin(), SectionHeading.end(), '[', ' ');
					}
						isHeading1=1;
				}
				//cout<<"Line after equal to : "<<line<<endl;
			}

			//The Following If statement checks for the bullets and removes it
			if(line[0]=='*')
			{
				//cout<<line<<endl;
				istringstream iss1(line);
				getline(iss1, token, ' ');
				getline(iss1, token, '\n');
				line=token;
				//cout<<line<<endl;
				//After this call the '[[' to remove the links from the line
			}

			std::string subline="";
            std::string link="";
            //The following if statement checks for the links in the line, generate a link repository, and also generate a category dictionary. Also it removes the lines after the last Category type line
			//This also generates a new line "subline" out of the "line". The subline contains the removed links and replaced link names
            if(line.rfind("[[")!=string::npos){

				//cout<<"Link line is "<<line<<endl;
				if(line.find("File:",0)<string::npos)
				{
					continue;
				}
				if(inCategory == 1 && line.find("Category:")>=string::npos ){
					continue;
				}
				std::string::size_type end_pos2( 0 );
				//std::string::size_type end_pos( 0 );
				std::string::size_type end_pos1( 0 );
				std::string::size_type mid_pos( 0 );

				while(end_pos2 < string::npos){

				    end_pos2=line.find("[[",end_pos2);
				    //cout<<end_pos1<<"and"<<end_pos2<<endl;
				    //cout<<line<<endl;
				    if(end_pos2 == string::npos)
				    	break;
				    if(end_pos1< end_pos2 ){
					    	subline=subline+line.substr(end_pos1,end_pos2-end_pos1);
				    }
				    else
				    {
				    	subline=subline+line.substr(end_pos1,end_pos1-end_pos2);
				    }

				    if(end_pos2 != string::npos){
						end_pos2+=2;
						mid_pos=line.find("|",end_pos2);
						end_pos1=line.find("]]",end_pos2);
                        if(end_pos1 >= string::npos){
                            string buffer = line.substr(end_pos2,string::npos);
                           	getline(ifs,line);
                           	end_pos1=line.find("]]",0);
                           	string buffer1= line.substr(0,end_pos1);
                           	link = buffer+buffer1;
                           	//cout<<"Concatnated string is"<<link<<endl;
                           	LinkList=LinkList.append(link+"$");
                           	end_pos1+=2;
                           	end_pos2=end_pos1;
                        }
    				    //cout<<mid_pos<<"and"<<end_pos1<<"and"<<end_pos2<<endl;
						//cout<<line<<endl;
						if(end_pos1 == 1)
							break;
                        if (mid_pos<end_pos1)
                        {
							link=line.substr(end_pos2,mid_pos-end_pos2);
                        }
                        else {
                         	link=line.substr(end_pos2,end_pos1-end_pos2);
                        }



                        subline=subline+link;

                        end_pos1+=2;

                        if(link.find("Category:",0)<string::npos)
                        {
                        	inCategory = 1;
							istringstream iss1(link);
							getline(iss1, token, ':');
							getline(iss1, token, '\n');
							CategoryList = CategoryList.append(token+"$");
							//Gassa comment out
							int categoryId = AuthCatDict->addCategory(token);
							categoryIndex->addCategoryPostingList(categoryId, doc.getDocId(), token);
							//if(CUtilities::categories.find(token) == string::npos)
								//CUtilities::categories.append(token+"%");
                        }//cout<<"LINK isss"<<link<<endl;
                        else{
                        	LinkList=LinkList.append(link+"$");
                        	//Gassa comment out
                        	AuthCatDict->addLinkPair(sourcename,link);
                        }
				    }
				}//end of while(end_pos2 < string::npos)

			}//end of if(rfind('[['))
			//cout<<subline<<endl;
            //The following if block replaces the original line with the generated subline
			if(subline != ""){
			line=""+subline;
			//cout<<"Line isss"<<line<<endl;
			}
			file_contents += line+"\n";
			//cout<<line<<endl;
			//The following 2 if blocks are used for writing section headings and the summary content(i.e., 100 chars after the heading) into sem wiki file
			if(isHeading == 1){
				if(line.rfind("[[File:")==string::npos && line[0] != '='){
					//SectionHeading=SectionHeading+line.substr(0,100)+"\n";
					isHeading = 0;
					isHeading1 = 0;
				}
				else if(line[0] == '='){
					//SectionHeading = SectionHeading+"\n";
					isHeading = 1;
					isHeading1 = 0;
				}

			}

			if(isHeading1 == 1){
				isHeading = 1;
				//isHeading1 = 0;
			}


		}//End of Main While Loop
		//cout<<AuthorList<<endl;
		//cout<<Timestamp<<endl;
		//cout<<infobox<<endl;
		//cout<<SectionHeading<<endl;
		//cout<<LinkList<<endl;
		//cout<<CategoryList<<endl;
		//CUtilities::authors.append("\n");
		//CUtilities::categories.append("\n");
		SectionHeading = SectionHeading+"\n";
		semWikiStream << ArticleName << DOCID << autH << AuthorList
						<< Timestamp << infH << infobox << secH << SectionHeading
						<< linH << LinkList << catH << CategoryList;
		file_contents=file_contents+infobox;
		replace(file_contents.begin(), file_contents.end(), '#', ' ');
		replace(file_contents.begin(), file_contents.end(), '{', ' ');
		replace(file_contents.begin(), file_contents.end(), '!', ' ');
		replace(file_contents.begin(), file_contents.end(), '}', ' ');
		replace(file_contents.begin(), file_contents.end(), '|', ' ');
		replace(file_contents.begin(), file_contents.end(), '<', ' ');
		replace(file_contents.begin(), file_contents.end(), '-', ' ');
		replace(file_contents.begin(), file_contents.end(), ':', ' ');
		replace(file_contents.begin(), file_contents.end(), '/', ' ');
		replace(file_contents.begin(), file_contents.end(), ']', ' ');
		replace(file_contents.begin(), file_contents.end(), '[', ' ');
		replace(file_contents.begin(), file_contents.end(), '\'', ' ');
		replace(file_contents.begin(), file_contents.end(), '\;', ' ');
		replace(file_contents.begin(), file_contents.end(), '>', ' ');
		replace(file_contents.begin(), file_contents.end(), '(', ' ');
		replace(file_contents.begin(), file_contents.end(), ')', ' ');
		replace(file_contents.begin(), file_contents.end(), '"', ' ');
		replace(file_contents.begin(), file_contents.end(), '=', ' ');
		replace(file_contents.begin(), file_contents.end(), '%', ' ');
		replace(file_contents.begin(), file_contents.end(), '*', ' ');

		cout<<"No of Sections is : "<<no_of_sections<<endl;
		cout<<"No of References is : "<<no_of_references<<endl;
		//cout<<file_contents<<endl;
		doc.setFile_contents(file_contents);

		doc.setNoOfSections(no_of_sections);
		doc.setNoOfReferences(no_of_references);

		// Static Score
		scoreCalc->initCatTermCountMap(doc, CategoryList);
		WhiteSpaceParser->parseText(doc);

		// For testing no_of_sections and no_of_references in CDOC --- Srivathsan

		/*int getsections = doc.getNo_of_Sections();
		int getrefs = doc.getNo_of_References();
		cout<<"No of Sections from CDoc : "<<getsections<<endl;
		cout<<"No of References from CDoc : "<<getrefs<<endl;
		*/

		// For Fwd Index
		typedef pair<int, string> sem;
		//cout << "Author: " << AuthorList;

		//map<int,string> semWikiData = doc.getSemWikiData();
		//semWikiData.insert(sem(AUTHOR, AuthorList));
		//semWikiData.insert(sem(CATEGORY, CategoryList));
		//semWikiData.insert(sem(SECTION, SectionHeading));
		// semWikiData.insert(sem(INFOBOX, infobox));
		//semWikiData.insert(sem(LINK, LinkList));

		//doc.setSemWikiData(semWikiData);
		//Gassa commment out
		//ForwardIndexGen* fwdIndex = ForwardIndexGen::getInstance();
		//fwdIndex->generateFwdIndex(doc, WIKI);

		//cout<<"AAAA"<<CUtilities::authors<<endl;

		semWikiStream.close();

	} else {
		cout << "Couldn't open file " << filename << endl;
	}

	ifs.close();

	// start parsing the file_contents
	cout << "file contents size = " << file_contents.size() << endl;

	status = parse(file_contents);

	// printing out the set of links - Diagnostics only
	set<string>::iterator s_itr;
	size_t link_counter = 1;
	/*cout << "Number of outgoing links = " << _outgoing_link_set.size() << endl;
	for ( s_itr = _outgoing_link_set.begin(); s_itr != _outgoing_link_set.end(); ++s_itr, link_counter++ ) {
		cout << "linking to ==> (#" << link_counter << ") " << *s_itr << endl;
	}*/

	// Calc & write Static Score
	scoreCalc->writeStaticScore(doc);
	return status;
}

/**
 * @brief
 * @param file_contents
 */
bool CWikiMarkupParser::parse(std::string file_contents) {
	bool status = false;

	// reset the parser for each wiki file parsed
	reset();

	// start parsing from the beginning of the string buffer
	size_t beg_pos = 0;
	size_t end_pos = file_contents.length();
	// put the parser in the character consume state
	_parser_state = _parser_cc_state;
	for ( size_t i = beg_pos; i < end_pos; ++i ) {
		_parser_state->execute(file_contents, i);
	}

	status = true;
	return status;
}

/**
 * @brief resets the parser state
 */
void CWikiMarkupParser::reset() {
	_parser_state = _parser_cc_state;
	_outgoing_link_set.clear();
}

/**
 * @brief constructor
 * @param parser
 */
CParserState::CParserState() {
	_buffer = "";
}

/**
 * @brief execute the parser based on the state that called this method
 * @param buffer
 * @param consume_index
 */
void CParserState::execute(string& buffer, size_t consume_index) {
	// do nothing for now

}

/**
 * @brief constructor
 * @param parser
 */
CWikiCharacterConsumeState::CWikiCharacterConsumeState(CWikiMarkupParser *parser) {
	CParserState::_parser = parser;
	_buffer = "";
}

/**
 * @brief execute the parser based on the state that called this method
 */
void CWikiCharacterConsumeState::execute(string& buffer, size_t consume_index) {
	if ( b_verbose_global ) cout << "cc_state: " << _buffer << endl;
	if ( b_verbose_global ) {
		if ( _b_wiki_link_seen ) cout << "cc s wiki_link = true: " << endl; else cout << "cc s wiki_link = false: " << endl;
	}

	switch (buffer[consume_index]) {
	case '[':
		_parser->set_state(_parser->get_wiki_partial_tag_state());
		break;
	case ']':
		_parser->set_state(_parser->get_wiki_partial_tag_state());
		break;
	case '|':

		if ( _b_wiki_link_seen ) {
			if ( b_verbose_global) cout << "cc s | : " << _buffer << endl;	// TODO-remove
			//_parser->get_outgoing_link_set().insert(_buffer);
			//_b_wiki_link_seen = false;
			_parser->set_state(_parser->get_wiki_link_end_state());
		} else
			_parser->set_state(_parser->get_wiki_character_consume_state());
		break;
	default:
		_buffer += buffer[consume_index];
		break;
	}
}

/**
 * @brief constructor
 * @param parser
 */
CWikiLinkBeginState::CWikiLinkBeginState(CWikiMarkupParser *parser) {
	CParserState::_parser = parser;
}

/**
 * @brief execute the parser based on the state that called this method
 */
void CWikiLinkBeginState::execute(string& buffer, size_t consume_index) {

	switch (buffer[consume_index]) {
	case '[':	// this is the third '[' in sequence - don't do anything

		break;
	case ']' :
		_parser->set_state(_parser->get_wiki_partial_tag_state());
		break;
	case '|' :
		_parser->set_state(_parser->get_wiki_partial_tag_state());
		break;
	default:

		CWikiCharacterConsumeState* state = reinterpret_cast<CWikiCharacterConsumeState*>(_parser->get_wiki_character_consume_state());
		state->set_b_wiki_link_seen(true);
		string temp_str(1, buffer[consume_index]);
		if ( b_verbose_global ) cout << "consume_index = " << consume_index << endl; //TODO--remove
		if ( b_verbose_global ) cout << "wlb s: " << temp_str << endl; // TODO remove
		state->set_buffer(temp_str);
		_parser->set_state(state);
		break;
	}
}

/**
 * @brief constructor
 * @param parser
 */
CWikiLinkEndState::CWikiLinkEndState(CWikiMarkupParser *parser) {
	CParserState::_parser = parser;
}

/**
 * @brief execute the parser based on the state that called this method
 */
void CWikiLinkEndState::execute(string& buffer, size_t consume_index) {
	switch (buffer[consume_index]) {
	case '[':
		_parser->set_state(_parser->get_wiki_link_begin_state());
		break;
	case ']':	// this is the third ']' in sequence - don't do anything
		_parser->set_state(_parser->get_wiki_character_consume_state());
		break;
	default:

		CWikiCharacterConsumeState* state = reinterpret_cast<CWikiCharacterConsumeState*>(_parser->get_wiki_character_consume_state());

		if ( state->get_b_wiki_link_seen() ) {
			if ( b_verbose_global ) cout << "wle s: " << state->get_string_buffer() << endl; // TODO remove
			_parser->get_outgoing_link_set().insert(state->get_string_buffer());
			state->set_b_wiki_link_seen(false);
		}

		string temp_str(1, buffer[consume_index]);
		state->set_buffer(temp_str);
		_parser->set_state(state);
		break;
	}
}

/**
 * @brief constructor
 * @param parser
 */
CWikiPartialTagState::CWikiPartialTagState(CWikiMarkupParser *parser) {
	CParserState::_parser = parser;
}

/**
 * @brief execute the parser based on the state that called this method
 */
void CWikiPartialTagState::execute(string& buffer, size_t consume_index) {
	switch (buffer[consume_index]) {
	case '[':
		_parser->set_state(_parser->get_wiki_link_begin_state());
		break;
	case ']':
		_parser->set_state(_parser->get_wiki_link_end_state());
		break;
	default:
		break;
	}
}

//Srihari Method to extract the infobox comntent
void CWikiMarkupParser::extractInfobox(ifstream &file, string &curLine,
		string &infobox) {
	if (curLine.find("{{infobox") == string::npos && curLine.find("{{Infobox")
			== string::npos && curLine.find("{{taxobox") == string::npos
			&& curLine.find("{{Taxobox") == string::npos) {
		// Not an Infobox or a Taxobox
		return;
	}

	int i = 0;
	int unmatchedBr = 0;

	do {
		for (i = curLine.find("{", 0); i != string::npos;) {
			unmatchedBr++;
			i = curLine.find("{", ++i);
		}
		for (i = curLine.find("}", 0); i != string::npos;) {
			unmatchedBr--;
			i = curLine.find("}", ++i);
		}
		infobox.append(curLine).append("\n");
		getline(file, curLine);
	} while (unmatchedBr != 0 && !file.eof());
}

int CWikiMarkupParser::countNoofRef(ifstream &file, string &curLine) {
	int noofref = 0;
	do {
			getline(file, curLine);
			if (!curLine.empty())
			{
				noofref++;
			}
	} while (curLine[0] != '=' && !file.eof());
	return noofref;
}
